using System.Collections.ObjectModel;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace WpfApp1.Services
{
    /// <summary>
    /// Socket服务端配置类
    /// </summary>
    public class SocketServerConfig
    {
        /// <summary>
        /// 监听IP地址
        /// </summary>
        public string ListenAddress { get; set; } = "192.168.0.116";
        
        /// <summary>
        /// 监听端口
        /// </summary>
        public int ListenPort { get; set; } = 1605;
        
        /// <summary>
        /// 最大连接数
        /// </summary>
        public int MaxConnections { get; set; } = 100;
        
        /// <summary>
        /// 缓冲区大小
        /// </summary>
        public int BufferSize { get; set; } = 1024;
    }

    /// <summary>
    /// 客户端连接信息
    /// </summary>
    public class ClientInfo
    {
        public string Id { get; set; } = "";
        public string RemoteEndPoint { get; set; } = "";
        public DateTime ConnectTime { get; set; }
        public TcpClient TcpClient { get; set; } = null!;
        public NetworkStream Stream { get; set; } = null!;
        public bool IsConnected { get; set; }
        public DateTime LastHeartbeat { get; set; }
        public int MessageCount { get; set; }
    }

    /// <summary>
    /// Socket服务端管理器
    /// 负责TCP Socket服务端监听、客户端连接管理和数据收发
    /// </summary>
    public class SocketServerManager
    {
        private readonly SocketServerConfig _config;
        private TcpListener? _tcpListener;
        private bool _isListening = false;
        private readonly Dictionary<string, ClientInfo> _clients = new();
        private readonly object _lock = new object();
        private CancellationTokenSource? _cancellationTokenSource;

        /// <summary>
        /// 服务器状态变化事件
        /// </summary>
        public event Action<bool>? ServerStateChanged;
        
        /// <summary>
        /// 客户端连接/断开事件
        /// </summary>
        public event Action<ClientInfo, bool>? ClientConnectionChanged;
        
        /// <summary>
        /// 消息接收事件
        /// </summary>
        public event Action<ClientInfo, string>? MessageReceived;
        
        /// <summary>
        /// 日志消息事件
        /// </summary>
        public event Action<string>? LogMessage;

        /// <summary>
        /// 客户端列表（只读）
        /// </summary>
        public IReadOnlyDictionary<string, ClientInfo> Clients
        {
            get
            {
                lock (_lock)
                {
                    return new Dictionary<string, ClientInfo>(_clients);
                }
            }
        }

        /// <summary>
        /// 服务器是否正在监听
        /// </summary>
        public bool IsListening => _isListening;

        public SocketServerManager(SocketServerConfig? config = null)
        {
            _config = config ?? new SocketServerConfig();
        }

        /// <summary>
        /// 启动服务器
        /// </summary>
        public async Task<bool> StartAsync()
        {
            try
            {
                if (_isListening)
                {
                    LogMessage?.Invoke("服务器已在运行中");
                    return true;
                }

                var ipAddress = IPAddress.Parse(_config.ListenAddress);
                _tcpListener = new TcpListener(ipAddress, _config.ListenPort);
                _tcpListener.Start();
                
                _isListening = true;
                _cancellationTokenSource = new CancellationTokenSource();
                
                LogMessage?.Invoke($"Socket服务器已启动，监听 {_config.ListenAddress}:{_config.ListenPort}");
                ServerStateChanged?.Invoke(true);

                // 开始监听客户端连接
                _ = Task.Run(() => AcceptClientsAsync(_cancellationTokenSource.Token));

                return true;
            }
            catch (Exception ex)
            {
                LogMessage?.Invoke($"启动服务器失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 停止服务器
        /// </summary>
        public void Stop()
        {
            try
            {
                if (!_isListening)
                {
                    LogMessage?.Invoke("服务器未在运行");
                    return;
                }

                _isListening = false;
                _cancellationTokenSource?.Cancel();

                // 断开所有客户端连接
                lock (_lock)
                {
                    foreach (var client in _clients.Values)
                    {
                        DisconnectClient(client);
                    }
                    _clients.Clear();
                }

                _tcpListener?.Stop();
                _cancellationTokenSource?.Dispose();

                LogMessage?.Invoke("Socket服务器已停止");
                ServerStateChanged?.Invoke(false);
            }
            catch (Exception ex)
            {
                LogMessage?.Invoke($"停止服务器时发生错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 监听客户端连接
        /// </summary>
        private async Task AcceptClientsAsync(CancellationToken cancellationToken)
        {
            while (_isListening && !cancellationToken.IsCancellationRequested)
            {
                try
                {
                    var tcpClient = await _tcpListener!.AcceptTcpClientAsync();
                    
                    var clientInfo = new ClientInfo
                    {
                        Id = Guid.NewGuid().ToString("N")[..8],
                        RemoteEndPoint = tcpClient.Client.RemoteEndPoint?.ToString() ?? "Unknown",
                        ConnectTime = DateTime.Now,
                        TcpClient = tcpClient,
                        Stream = tcpClient.GetStream(),
                        IsConnected = true,
                        LastHeartbeat = DateTime.Now
                    };

                    lock (_lock)
                    {
                        _clients[clientInfo.Id] = clientInfo;
                    }

                    LogMessage?.Invoke($"新客户端连接: {clientInfo.RemoteEndPoint} (ID: {clientInfo.Id})");
                    ClientConnectionChanged?.Invoke(clientInfo, true);

                    // 为每个客户端启动数据接收任务
                    _ = Task.Run(() => HandleClientAsync(clientInfo, cancellationToken));
                }
                catch (ObjectDisposedException)
                {
                    // 服务器已停止
                    break;
                }
                catch (Exception ex)
                {
                    if (_isListening)
                    {
                        LogMessage?.Invoke($"接受客户端连接时发生错误: {ex.Message}");
                    }
                }
            }
        }

        /// <summary>
        /// 处理客户端数据
        /// </summary>
        private async Task HandleClientAsync(ClientInfo clientInfo, CancellationToken cancellationToken)
        {
            var buffer = new byte[_config.BufferSize];

            try
            {
                while (clientInfo.IsConnected && !cancellationToken.IsCancellationRequested)
                {
                    if (!clientInfo.TcpClient.Connected)
                    {
                        break;
                    }

                    int bytesRead = await clientInfo.Stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
                    
                    if (bytesRead > 0)
                    {
                        string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                        clientInfo.LastHeartbeat = DateTime.Now;
                        clientInfo.MessageCount++;
                        
                        LogMessage?.Invoke($"收到来自 {clientInfo.RemoteEndPoint} 的消息: {message}");
                        MessageReceived?.Invoke(clientInfo, message);

                        // 回显消息给客户端
                        await SendToClientAsync(clientInfo.Id, $"服务器回复: {message} (时间: {DateTime.Now:HH:mm:ss})");
                    }
                    else
                    {
                        // 客户端断开连接
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                LogMessage?.Invoke($"处理客户端 {clientInfo.RemoteEndPoint} 数据时发生错误: {ex.Message}");
            }
            finally
            {
                // 移除客户端
                lock (_lock)
                {
                    if (_clients.ContainsKey(clientInfo.Id))
                    {
                        _clients.Remove(clientInfo.Id);
                    }
                }

                DisconnectClient(clientInfo);
                LogMessage?.Invoke($"客户端 {clientInfo.RemoteEndPoint} 已断开连接");
                ClientConnectionChanged?.Invoke(clientInfo, false);
            }
        }

        /// <summary>
        /// 发送消息给指定客户端
        /// </summary>
        public async Task<bool> SendToClientAsync(string clientId, string message)
        {
            try
            {
                lock (_lock)
                {
                    if (!_clients.TryGetValue(clientId, out var client) || !client.IsConnected)
                    {
                        LogMessage?.Invoke($"客户端 {clientId} 不存在或已断开连接");
                        return false;
                    }

                    var data = Encoding.UTF8.GetBytes(message);
                    client.Stream.WriteAsync(data, 0, data.Length);
                    LogMessage?.Invoke($"发送消息给客户端 {client.RemoteEndPoint}: {message}");
                    return true;
                }
            }
            catch (Exception ex)
            {
                LogMessage?.Invoke($"发送消息给客户端 {clientId} 时发生错误: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 广播消息给所有客户端
        /// </summary>
        public async Task<int> BroadcastAsync(string message)
        {
            int successCount = 0;
            var clientsCopy = Clients;

            foreach (var client in clientsCopy.Values)
            {
                if (await SendToClientAsync(client.Id, message))
                {
                    successCount++;
                }
            }

            LogMessage?.Invoke($"广播消息给 {successCount}/{clientsCopy.Count} 个客户端: {message}");
            return successCount;
        }

        /// <summary>
        /// 断开指定客户端
        /// </summary>
        public void DisconnectClient(string clientId)
        {
            lock (_lock)
            {
                if (_clients.TryGetValue(clientId, out var client))
                {
                    DisconnectClient(client);
                    _clients.Remove(clientId);
                }
            }
        }

        /// <summary>
        /// 断开客户端连接
        /// </summary>
        private void DisconnectClient(ClientInfo client)
        {
            try
            {
                client.IsConnected = false;
                client.Stream?.Close();
                client.TcpClient?.Close();
            }
            catch (Exception ex)
            {
                LogMessage?.Invoke($"断开客户端连接时发生错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取服务器统计信息
        /// </summary>
        public string GetServerStats()
        {
            var connectedCount = Clients.Count;
            var totalMessages = Clients.Values.Sum(c => c.MessageCount);
            return $"连接客户端: {connectedCount}, 总消息数: {totalMessages}";
        }
    }
}